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 |