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