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