| 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 "media/cdm/aes_decryptor.h" | 5 #include "media/cdm/aes_decryptor.h" |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 return; | 327 return; |
| 328 } | 328 } |
| 329 | 329 |
| 330 // Make sure that at least one key was extracted. | 330 // Make sure that at least one key was extracted. |
| 331 if (keys.empty()) { | 331 if (keys.empty()) { |
| 332 promise->reject( | 332 promise->reject( |
| 333 INVALID_ACCESS_ERROR, 0, "Response does not contain any keys."); | 333 INVALID_ACCESS_ERROR, 0, "Response does not contain any keys."); |
| 334 return; | 334 return; |
| 335 } | 335 } |
| 336 | 336 |
| 337 bool key_added = false; |
| 337 for (KeyIdAndKeyPairs::iterator it = keys.begin(); it != keys.end(); ++it) { | 338 for (KeyIdAndKeyPairs::iterator it = keys.begin(); it != keys.end(); ++it) { |
| 338 if (it->second.length() != | 339 if (it->second.length() != |
| 339 static_cast<size_t>(DecryptConfig::kDecryptionKeySize)) { | 340 static_cast<size_t>(DecryptConfig::kDecryptionKeySize)) { |
| 340 DVLOG(1) << "Invalid key length: " << it->second.length(); | 341 DVLOG(1) << "Invalid key length: " << it->second.length(); |
| 341 promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid key length."); | 342 promise->reject(INVALID_ACCESS_ERROR, 0, "Invalid key length."); |
| 342 return; | 343 return; |
| 343 } | 344 } |
| 345 |
| 346 // If this key_id doesn't currently exist in this session, |
| 347 // a new key is added. |
| 348 if (!HasKey(session_id, it->first)) |
| 349 key_added = true; |
| 350 |
| 344 if (!AddDecryptionKey(session_id, it->first, it->second)) { | 351 if (!AddDecryptionKey(session_id, it->first, it->second)) { |
| 345 promise->reject(INVALID_ACCESS_ERROR, 0, "Unable to add key."); | 352 promise->reject(INVALID_ACCESS_ERROR, 0, "Unable to add key."); |
| 346 return; | 353 return; |
| 347 } | 354 } |
| 348 } | 355 } |
| 349 | 356 |
| 350 { | 357 { |
| 351 base::AutoLock auto_lock(new_key_cb_lock_); | 358 base::AutoLock auto_lock(new_key_cb_lock_); |
| 352 | 359 |
| 353 if (!new_audio_key_cb_.is_null()) | 360 if (!new_audio_key_cb_.is_null()) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 367 if (item.second->Contains(session_id)) { | 374 if (item.second->Contains(session_id)) { |
| 368 scoped_ptr<CdmKeyInformation> key_info(new CdmKeyInformation); | 375 scoped_ptr<CdmKeyInformation> key_info(new CdmKeyInformation); |
| 369 key_info->key_id.assign(item.first.begin(), item.first.end()); | 376 key_info->key_id.assign(item.first.begin(), item.first.end()); |
| 370 key_info->status = CdmKeyInformation::USABLE; | 377 key_info->status = CdmKeyInformation::USABLE; |
| 371 key_info->system_code = 0; | 378 key_info->system_code = 0; |
| 372 keys_info.push_back(key_info.release()); | 379 keys_info.push_back(key_info.release()); |
| 373 } | 380 } |
| 374 } | 381 } |
| 375 } | 382 } |
| 376 | 383 |
| 377 // Assume that at least 1 new key has been successfully added and thus | 384 session_keys_change_cb_.Run(session_id, key_added, keys_info.Pass()); |
| 378 // sending true for |has_additional_usable_key|. http://crbug.com/448219. | |
| 379 session_keys_change_cb_.Run(session_id, true, keys_info.Pass()); | |
| 380 } | 385 } |
| 381 | 386 |
| 382 void AesDecryptor::CloseSession(const std::string& session_id, | 387 void AesDecryptor::CloseSession(const std::string& session_id, |
| 383 scoped_ptr<SimpleCdmPromise> promise) { | 388 scoped_ptr<SimpleCdmPromise> promise) { |
| 384 // Validate that this is a reference to an active session and then forget it. | 389 // Validate that this is a reference to an active session and then forget it. |
| 385 std::set<std::string>::iterator it = valid_sessions_.find(session_id); | 390 std::set<std::string>::iterator it = valid_sessions_.find(session_id); |
| 386 DCHECK(it != valid_sessions_.end()); | 391 DCHECK(it != valid_sessions_.end()); |
| 387 | 392 |
| 388 valid_sessions_.erase(it); | 393 valid_sessions_.erase(it); |
| 389 | 394 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 const std::string& key_id) const { | 544 const std::string& key_id) const { |
| 540 base::AutoLock auto_lock(key_map_lock_); | 545 base::AutoLock auto_lock(key_map_lock_); |
| 541 KeyIdToSessionKeysMap::const_iterator key_id_found = key_map_.find(key_id); | 546 KeyIdToSessionKeysMap::const_iterator key_id_found = key_map_.find(key_id); |
| 542 if (key_id_found == key_map_.end()) | 547 if (key_id_found == key_map_.end()) |
| 543 return NULL; | 548 return NULL; |
| 544 | 549 |
| 545 // Return the key from the "latest" session_id entry. | 550 // Return the key from the "latest" session_id entry. |
| 546 return key_id_found->second->LatestDecryptionKey(); | 551 return key_id_found->second->LatestDecryptionKey(); |
| 547 } | 552 } |
| 548 | 553 |
| 554 bool AesDecryptor::HasKey(const std::string& session_id, |
| 555 const std::string& key_id) { |
| 556 base::AutoLock auto_lock(key_map_lock_); |
| 557 KeyIdToSessionKeysMap::const_iterator key_id_found = key_map_.find(key_id); |
| 558 if (key_id_found == key_map_.end()) |
| 559 return false; |
| 560 |
| 561 return key_id_found->second->Contains(session_id); |
| 562 } |
| 563 |
| 549 void AesDecryptor::DeleteKeysForSession(const std::string& session_id) { | 564 void AesDecryptor::DeleteKeysForSession(const std::string& session_id) { |
| 550 base::AutoLock auto_lock(key_map_lock_); | 565 base::AutoLock auto_lock(key_map_lock_); |
| 551 | 566 |
| 552 // Remove all keys associated with |session_id|. Since the data is | 567 // Remove all keys associated with |session_id|. Since the data is |
| 553 // optimized for access in GetKey(), we need to look at each entry in | 568 // optimized for access in GetKey(), we need to look at each entry in |
| 554 // |key_map_|. | 569 // |key_map_|. |
| 555 KeyIdToSessionKeysMap::iterator it = key_map_.begin(); | 570 KeyIdToSessionKeysMap::iterator it = key_map_.begin(); |
| 556 while (it != key_map_.end()) { | 571 while (it != key_map_.end()) { |
| 557 it->second->Erase(session_id); | 572 it->second->Erase(session_id); |
| 558 if (it->second->Empty()) { | 573 if (it->second->Empty()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 576 bool AesDecryptor::DecryptionKey::Init() { | 591 bool AesDecryptor::DecryptionKey::Init() { |
| 577 CHECK(!secret_.empty()); | 592 CHECK(!secret_.empty()); |
| 578 decryption_key_.reset(crypto::SymmetricKey::Import( | 593 decryption_key_.reset(crypto::SymmetricKey::Import( |
| 579 crypto::SymmetricKey::AES, secret_)); | 594 crypto::SymmetricKey::AES, secret_)); |
| 580 if (!decryption_key_) | 595 if (!decryption_key_) |
| 581 return false; | 596 return false; |
| 582 return true; | 597 return true; |
| 583 } | 598 } |
| 584 | 599 |
| 585 } // namespace media | 600 } // namespace media |
| OLD | NEW |