| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string> | 5 #include <string> |
| 6 #include <vector> | 6 #include <vector> |
| 7 | 7 |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 } | 204 } |
| 205 | 205 |
| 206 enum PromiseResult { RESOLVED, REJECTED }; | 206 enum PromiseResult { RESOLVED, REJECTED }; |
| 207 | 207 |
| 208 class AesDecryptorTest : public testing::Test { | 208 class AesDecryptorTest : public testing::Test { |
| 209 public: | 209 public: |
| 210 AesDecryptorTest() | 210 AesDecryptorTest() |
| 211 : decryptor_(base::Bind(&AesDecryptorTest::OnSessionMessage, | 211 : decryptor_(base::Bind(&AesDecryptorTest::OnSessionMessage, |
| 212 base::Unretained(this)), | 212 base::Unretained(this)), |
| 213 base::Bind(&AesDecryptorTest::OnSessionClosed, | 213 base::Bind(&AesDecryptorTest::OnSessionClosed, |
| 214 base::Unretained(this)), |
| 215 base::Bind(&AesDecryptorTest::OnSessionKeysChange, |
| 214 base::Unretained(this))), | 216 base::Unretained(this))), |
| 215 decrypt_cb_(base::Bind(&AesDecryptorTest::BufferDecrypted, | 217 decrypt_cb_(base::Bind(&AesDecryptorTest::BufferDecrypted, |
| 216 base::Unretained(this))), | 218 base::Unretained(this))), |
| 217 original_data_(kOriginalData, kOriginalData + kOriginalDataSize), | 219 original_data_(kOriginalData, kOriginalData + kOriginalDataSize), |
| 218 encrypted_data_(kEncryptedData, | 220 encrypted_data_(kEncryptedData, |
| 219 kEncryptedData + arraysize(kEncryptedData)), | 221 kEncryptedData + arraysize(kEncryptedData)), |
| 220 subsample_encrypted_data_( | 222 subsample_encrypted_data_( |
| 221 kSubsampleEncryptedData, | 223 kSubsampleEncryptedData, |
| 222 kSubsampleEncryptedData + arraysize(kSubsampleEncryptedData)), | 224 kSubsampleEncryptedData + arraysize(kSubsampleEncryptedData)), |
| 223 key_id_(kKeyId, kKeyId + arraysize(kKeyId)), | 225 key_id_(kKeyId, kKeyId + arraysize(kKeyId)), |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 decryptor_.CreateSession(std::string(), | 302 decryptor_.CreateSession(std::string(), |
| 301 &key_id[0], | 303 &key_id[0], |
| 302 key_id.size(), | 304 key_id.size(), |
| 303 MediaKeys::TEMPORARY_SESSION, | 305 MediaKeys::TEMPORARY_SESSION, |
| 304 CreateSessionPromise(RESOLVED)); | 306 CreateSessionPromise(RESOLVED)); |
| 305 // This expects the promise to be called synchronously, which is the case | 307 // This expects the promise to be called synchronously, which is the case |
| 306 // for AesDecryptor. | 308 // for AesDecryptor. |
| 307 return web_session_id_; | 309 return web_session_id_; |
| 308 } | 310 } |
| 309 | 311 |
| 310 // Releases the session specified by |session_id|. | 312 // Closes the session specified by |session_id|. |
| 311 void ReleaseSession(const std::string& session_id) { | 313 void CloseSession(const std::string& session_id) { |
| 312 EXPECT_CALL(*this, OnSessionClosed(session_id)); | 314 EXPECT_CALL(*this, OnSessionClosed(session_id)); |
| 313 decryptor_.ReleaseSession(session_id, CreatePromise(RESOLVED)); | 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)); |
| 314 } | 325 } |
| 315 | 326 |
| 316 // Updates the session specified by |session_id| with |key|. |result| | 327 // Updates the session specified by |session_id| with |key|. |result| |
| 317 // tests that the update succeeds or generates an error. | 328 // tests that the update succeeds or generates an error. |
| 318 void UpdateSessionAndExpect(std::string session_id, | 329 void UpdateSessionAndExpect(std::string session_id, |
| 319 const std::string& key, | 330 const std::string& key, |
| 320 PromiseResult result) { | 331 PromiseResult expected_result) { |
| 321 DCHECK(!key.empty()); | 332 DCHECK(!key.empty()); |
| 322 | 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 |
| 323 decryptor_.UpdateSession(session_id, | 340 decryptor_.UpdateSession(session_id, |
| 324 reinterpret_cast<const uint8*>(key.c_str()), | 341 reinterpret_cast<const uint8*>(key.c_str()), |
| 325 key.length(), | 342 key.length(), |
| 326 CreatePromise(result)); | 343 CreatePromise(expected_result)); |
| 327 } | 344 } |
| 328 | 345 |
| 329 void GetUsableKeyIdsAndExpect(const std::string& session_id, | 346 void GetUsableKeyIdsAndExpect(const std::string& session_id, |
| 330 PromiseResult expected_result, | 347 PromiseResult expected_result, |
| 331 uint32 expected_count) { | 348 uint32 expected_count) { |
| 332 decryptor_.GetUsableKeyIds( | 349 decryptor_.GetUsableKeyIds( |
| 333 session_id, CreateUsableKeyIdsPromise(expected_result, expected_count)); | 350 session_id, CreateUsableKeyIdsPromise(expected_result, expected_count)); |
| 334 } | 351 } |
| 335 | 352 |
| 336 bool UsableKeyIdsContains(std::vector<uint8> expected) { | 353 bool UsableKeyIdsContains(std::vector<uint8> expected) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 case NO_KEY: | 416 case NO_KEY: |
| 400 EXPECT_TRUE(decrypted_text.empty()); | 417 EXPECT_TRUE(decrypted_text.empty()); |
| 401 break; | 418 break; |
| 402 } | 419 } |
| 403 } | 420 } |
| 404 | 421 |
| 405 MOCK_METHOD3(OnSessionMessage, | 422 MOCK_METHOD3(OnSessionMessage, |
| 406 void(const std::string& web_session_id, | 423 void(const std::string& web_session_id, |
| 407 const std::vector<uint8>& message, | 424 const std::vector<uint8>& message, |
| 408 const GURL& destination_url)); | 425 const GURL& destination_url)); |
| 426 MOCK_METHOD2(OnSessionKeysChange, |
| 427 void(const std::string& web_session_id, |
| 428 bool has_additional_usable_key)); |
| 409 MOCK_METHOD1(OnSessionClosed, void(const std::string& web_session_id)); | 429 MOCK_METHOD1(OnSessionClosed, void(const std::string& web_session_id)); |
| 410 | 430 |
| 411 AesDecryptor decryptor_; | 431 AesDecryptor decryptor_; |
| 412 AesDecryptor::DecryptCB decrypt_cb_; | 432 AesDecryptor::DecryptCB decrypt_cb_; |
| 413 std::string web_session_id_; | 433 std::string web_session_id_; |
| 414 | 434 |
| 415 // Copy of the vector from the last successful call to | 435 // Copy of the vector from the last successful call to |
| 416 // OnResolveWithUsableKeyIds(). | 436 // OnResolveWithUsableKeyIds(). |
| 417 KeyIdsVector useable_key_ids_; | 437 KeyIdsVector useable_key_ids_; |
| 418 | 438 |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 | 660 |
| 641 std::vector<SubsampleEntry> cypher_only_subsample_entries( | 661 std::vector<SubsampleEntry> cypher_only_subsample_entries( |
| 642 kSubsampleEntriesCypherOnly, | 662 kSubsampleEntriesCypherOnly, |
| 643 kSubsampleEntriesCypherOnly + arraysize(kSubsampleEntriesCypherOnly)); | 663 kSubsampleEntriesCypherOnly + arraysize(kSubsampleEntriesCypherOnly)); |
| 644 | 664 |
| 645 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( | 665 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( |
| 646 encrypted_data_, key_id_, iv_, cypher_only_subsample_entries); | 666 encrypted_data_, key_id_, iv_, cypher_only_subsample_entries); |
| 647 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS); | 667 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS); |
| 648 } | 668 } |
| 649 | 669 |
| 650 TEST_F(AesDecryptorTest, ReleaseSession) { | 670 TEST_F(AesDecryptorTest, CloseSession) { |
| 651 std::string session_id = CreateSession(key_id_); | 671 std::string session_id = CreateSession(key_id_); |
| 652 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( | 672 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( |
| 653 encrypted_data_, key_id_, iv_, no_subsample_entries_); | 673 encrypted_data_, key_id_, iv_, no_subsample_entries_); |
| 674 |
| 675 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED); |
| 676 ASSERT_NO_FATAL_FAILURE( |
| 677 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); |
| 678 |
| 679 CloseSession(session_id); |
| 680 } |
| 681 |
| 682 TEST_F(AesDecryptorTest, RemoveSession) { |
| 683 // TODO(jrummell): Clean this up when the prefixed API is removed. |
| 684 // http://crbug.com/249976. |
| 685 std::string session_id = CreateSession(key_id_); |
| 686 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( |
| 687 encrypted_data_, key_id_, iv_, no_subsample_entries_); |
| 654 | 688 |
| 655 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED); | 689 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED); |
| 656 ASSERT_NO_FATAL_FAILURE( | 690 ASSERT_NO_FATAL_FAILURE( |
| 657 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); | 691 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); |
| 658 | 692 |
| 659 ReleaseSession(session_id); | 693 RemoveSession(session_id); |
| 660 } | 694 } |
| 661 | 695 |
| 662 TEST_F(AesDecryptorTest, NoKeyAfterReleaseSession) { | 696 TEST_F(AesDecryptorTest, NoKeyAfterCloseSession) { |
| 663 std::string session_id = CreateSession(key_id_); | 697 std::string session_id = CreateSession(key_id_); |
| 664 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( | 698 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( |
| 665 encrypted_data_, key_id_, iv_, no_subsample_entries_); | 699 encrypted_data_, key_id_, iv_, no_subsample_entries_); |
| 666 | 700 |
| 667 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED); | 701 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED); |
| 668 ASSERT_NO_FATAL_FAILURE( | 702 ASSERT_NO_FATAL_FAILURE( |
| 669 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); | 703 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); |
| 670 | 704 |
| 671 ReleaseSession(session_id); | 705 CloseSession(session_id); |
| 672 ASSERT_NO_FATAL_FAILURE( | 706 ASSERT_NO_FATAL_FAILURE( |
| 673 DecryptAndExpect(encrypted_buffer, original_data_, NO_KEY)); | 707 DecryptAndExpect(encrypted_buffer, original_data_, NO_KEY)); |
| 674 } | 708 } |
| 675 | 709 |
| 676 TEST_F(AesDecryptorTest, LatestKeyUsed) { | 710 TEST_F(AesDecryptorTest, LatestKeyUsed) { |
| 677 std::string session_id1 = CreateSession(key_id_); | 711 std::string session_id1 = CreateSession(key_id_); |
| 678 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( | 712 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( |
| 679 encrypted_data_, key_id_, iv_, no_subsample_entries_); | 713 encrypted_data_, key_id_, iv_, no_subsample_entries_); |
| 680 | 714 |
| 681 // Add alternate key, buffer should not be decoded properly. | 715 // Add alternate key, buffer should not be decoded properly. |
| 682 UpdateSessionAndExpect(session_id1, kKeyAlternateAsJWK, RESOLVED); | 716 UpdateSessionAndExpect(session_id1, kKeyAlternateAsJWK, RESOLVED); |
| 683 ASSERT_NO_FATAL_FAILURE( | 717 ASSERT_NO_FATAL_FAILURE( |
| 684 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH)); | 718 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH)); |
| 685 | 719 |
| 686 // Create a second session with a correct key value for key_id_. | 720 // Create a second session with a correct key value for key_id_. |
| 687 std::string session_id2 = CreateSession(key_id_); | 721 std::string session_id2 = CreateSession(key_id_); |
| 688 UpdateSessionAndExpect(session_id2, kKeyAsJWK, RESOLVED); | 722 UpdateSessionAndExpect(session_id2, kKeyAsJWK, RESOLVED); |
| 689 | 723 |
| 690 // Should be able to decode with latest key. | 724 // Should be able to decode with latest key. |
| 691 ASSERT_NO_FATAL_FAILURE( | 725 ASSERT_NO_FATAL_FAILURE( |
| 692 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); | 726 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); |
| 693 } | 727 } |
| 694 | 728 |
| 695 TEST_F(AesDecryptorTest, LatestKeyUsedAfterReleaseSession) { | 729 TEST_F(AesDecryptorTest, LatestKeyUsedAfterCloseSession) { |
| 696 std::string session_id1 = CreateSession(key_id_); | 730 std::string session_id1 = CreateSession(key_id_); |
| 697 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( | 731 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer( |
| 698 encrypted_data_, key_id_, iv_, no_subsample_entries_); | 732 encrypted_data_, key_id_, iv_, no_subsample_entries_); |
| 699 UpdateSessionAndExpect(session_id1, kKeyAsJWK, RESOLVED); | 733 UpdateSessionAndExpect(session_id1, kKeyAsJWK, RESOLVED); |
| 700 ASSERT_NO_FATAL_FAILURE( | 734 ASSERT_NO_FATAL_FAILURE( |
| 701 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); | 735 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); |
| 702 | 736 |
| 703 // Create a second session with a different key value for key_id_. | 737 // Create a second session with a different key value for key_id_. |
| 704 std::string session_id2 = CreateSession(key_id_); | 738 std::string session_id2 = CreateSession(key_id_); |
| 705 UpdateSessionAndExpect(session_id2, kKeyAlternateAsJWK, RESOLVED); | 739 UpdateSessionAndExpect(session_id2, kKeyAlternateAsJWK, RESOLVED); |
| 706 | 740 |
| 707 // Should not be able to decode with new key. | 741 // Should not be able to decode with new key. |
| 708 ASSERT_NO_FATAL_FAILURE( | 742 ASSERT_NO_FATAL_FAILURE( |
| 709 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH)); | 743 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH)); |
| 710 | 744 |
| 711 // Close second session, should revert to original key. | 745 // Close second session, should revert to original key. |
| 712 ReleaseSession(session_id2); | 746 CloseSession(session_id2); |
| 713 ASSERT_NO_FATAL_FAILURE( | 747 ASSERT_NO_FATAL_FAILURE( |
| 714 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); | 748 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS)); |
| 715 } | 749 } |
| 716 | 750 |
| 717 TEST_F(AesDecryptorTest, JWKKey) { | 751 TEST_F(AesDecryptorTest, JWKKey) { |
| 718 std::string session_id = CreateSession(key_id_); | 752 std::string session_id = CreateSession(key_id_); |
| 719 | 753 |
| 720 // Try a simple JWK key (i.e. not in a set) | 754 // Try a simple JWK key (i.e. not in a set) |
| 721 const std::string kJwkSimple = | 755 const std::string kJwkSimple = |
| 722 "{" | 756 "{" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 "{" | 868 "{" |
| 835 " \"keys\": [" | 869 " \"keys\": [" |
| 836 " {" | 870 " {" |
| 837 " \"kty\": \"oct\"," | 871 " \"kty\": \"oct\"," |
| 838 " \"kid\": \"\"," | 872 " \"kid\": \"\"," |
| 839 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" | 873 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\"" |
| 840 " }" | 874 " }" |
| 841 " ]" | 875 " ]" |
| 842 "}"; | 876 "}"; |
| 843 UpdateSessionAndExpect(session_id, kJwksWithEmptyKeyId, REJECTED); | 877 UpdateSessionAndExpect(session_id, kJwksWithEmptyKeyId, REJECTED); |
| 844 ReleaseSession(session_id); | 878 CloseSession(session_id); |
| 845 } | 879 } |
| 846 | 880 |
| 847 TEST_F(AesDecryptorTest, GetKeyIds) { | 881 TEST_F(AesDecryptorTest, GetKeyIds) { |
| 848 std::vector<uint8> key_id1(kKeyId, kKeyId + arraysize(kKeyId)); | 882 std::vector<uint8> key_id1(kKeyId, kKeyId + arraysize(kKeyId)); |
| 849 std::vector<uint8> key_id2(kKeyId2, kKeyId2 + arraysize(kKeyId2)); | 883 std::vector<uint8> key_id2(kKeyId2, kKeyId2 + arraysize(kKeyId2)); |
| 850 | 884 |
| 851 std::string session_id = CreateSession(key_id_); | 885 std::string session_id = CreateSession(key_id_); |
| 852 GetUsableKeyIdsAndExpect(session_id, RESOLVED, 0); | 886 GetUsableKeyIdsAndExpect(session_id, RESOLVED, 0); |
| 853 EXPECT_FALSE(UsableKeyIdsContains(key_id1)); | 887 EXPECT_FALSE(UsableKeyIdsContains(key_id1)); |
| 854 EXPECT_FALSE(UsableKeyIdsContains(key_id2)); | 888 EXPECT_FALSE(UsableKeyIdsContains(key_id2)); |
| 855 | 889 |
| 856 // Add 1 key, verify ID is returned. | 890 // Add 1 key, verify ID is returned. |
| 857 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED); | 891 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED); |
| 858 GetUsableKeyIdsAndExpect(session_id, RESOLVED, 1); | 892 GetUsableKeyIdsAndExpect(session_id, RESOLVED, 1); |
| 859 EXPECT_TRUE(UsableKeyIdsContains(key_id1)); | 893 EXPECT_TRUE(UsableKeyIdsContains(key_id1)); |
| 860 EXPECT_FALSE(UsableKeyIdsContains(key_id2)); | 894 EXPECT_FALSE(UsableKeyIdsContains(key_id2)); |
| 861 | 895 |
| 862 // Add second key, verify both IDs returned. | 896 // Add second key, verify both IDs returned. |
| 863 UpdateSessionAndExpect(session_id, kKey2AsJWK, RESOLVED); | 897 UpdateSessionAndExpect(session_id, kKey2AsJWK, RESOLVED); |
| 864 GetUsableKeyIdsAndExpect(session_id, RESOLVED, 2); | 898 GetUsableKeyIdsAndExpect(session_id, RESOLVED, 2); |
| 865 EXPECT_TRUE(UsableKeyIdsContains(key_id1)); | 899 EXPECT_TRUE(UsableKeyIdsContains(key_id1)); |
| 866 EXPECT_TRUE(UsableKeyIdsContains(key_id2)); | 900 EXPECT_TRUE(UsableKeyIdsContains(key_id2)); |
| 867 } | 901 } |
| 868 | 902 |
| 869 } // namespace media | 903 } // namespace media |
| OLD | NEW |