Chromium Code Reviews| 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" |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "crypto/encryptor.h" | 13 #include "crypto/encryptor.h" |
| 14 #include "crypto/symmetric_key.h" | 14 #include "crypto/symmetric_key.h" |
| 15 #include "media/base/audio_decoder_config.h" | 15 #include "media/base/audio_decoder_config.h" |
| 16 #include "media/base/decoder_buffer.h" | 16 #include "media/base/decoder_buffer.h" |
| 17 #include "media/base/decrypt_config.h" | 17 #include "media/base/decrypt_config.h" |
| 18 #include "media/base/media_keys_session_promise.h" | |
| 18 #include "media/base/video_decoder_config.h" | 19 #include "media/base/video_decoder_config.h" |
| 19 #include "media/base/video_frame.h" | 20 #include "media/base/video_frame.h" |
| 20 #include "media/cdm/json_web_key.h" | 21 #include "media/cdm/json_web_key.h" |
| 21 | 22 |
| 22 namespace media { | 23 namespace media { |
| 23 | 24 |
| 24 // Keeps track of the session IDs and DecryptionKeys. The keys are ordered by | 25 // Keeps track of the session IDs and DecryptionKeys. The keys are ordered by |
| 25 // insertion time (last insertion is first). It takes ownership of the | 26 // insertion time (last insertion is first). It takes ownership of the |
| 26 // DecryptionKeys. | 27 // DecryptionKeys. |
| 27 class AesDecryptor::SessionIdDecryptionKeyMap { | 28 class AesDecryptor::SessionIdDecryptionKeyMap { |
| 28 // Use a std::list to actually hold the data. Insertion is always done | 29 // Use a std::list to actually hold the data. Insertion is always done |
| 29 // at the front, so the "latest" decryption key is always the first one | 30 // at the front, so the "latest" decryption key is always the first one |
| 30 // in the list. | 31 // in the list. |
| 31 typedef std::list<std::pair<uint32, DecryptionKey*> > KeyList; | 32 typedef std::list<std::pair<std::string, DecryptionKey*> > KeyList; |
| 32 | 33 |
| 33 public: | 34 public: |
| 34 SessionIdDecryptionKeyMap() {} | 35 SessionIdDecryptionKeyMap() {} |
| 35 ~SessionIdDecryptionKeyMap() { STLDeleteValues(&key_list_); } | 36 ~SessionIdDecryptionKeyMap() { STLDeleteValues(&key_list_); } |
| 36 | 37 |
| 37 // Replaces value if |session_id| is already present, or adds it if not. | 38 // Replaces value if |session_id| is already present, or adds it if not. |
| 38 // This |decryption_key| becomes the latest until another insertion or | 39 // This |decryption_key| becomes the latest until another insertion or |
| 39 // |session_id| is erased. | 40 // |session_id| is erased. |
| 40 void Insert(uint32 session_id, scoped_ptr<DecryptionKey> decryption_key); | 41 void Insert(const std::string& web_session_id, |
| 42 scoped_ptr<DecryptionKey> decryption_key); | |
| 41 | 43 |
| 42 // Deletes the entry for |session_id| if present. | 44 // Deletes the entry for |session_id| if present. |
| 43 void Erase(const uint32 session_id); | 45 void Erase(const std::string& web_session_id); |
| 44 | 46 |
| 45 // Returns whether the list is empty | 47 // Returns whether the list is empty |
| 46 bool Empty() const { return key_list_.empty(); } | 48 bool Empty() const { return key_list_.empty(); } |
| 47 | 49 |
| 48 // Returns the last inserted DecryptionKey. | 50 // Returns the last inserted DecryptionKey. |
| 49 DecryptionKey* LatestDecryptionKey() { | 51 DecryptionKey* LatestDecryptionKey() { |
| 50 DCHECK(!key_list_.empty()); | 52 DCHECK(!key_list_.empty()); |
| 51 return key_list_.begin()->second; | 53 return key_list_.begin()->second; |
| 52 } | 54 } |
| 53 | 55 |
| 54 private: | 56 private: |
| 55 // Searches the list for an element with |session_id|. | 57 // Searches the list for an element with |web_session_id|. |
| 56 KeyList::iterator Find(const uint32 session_id); | 58 KeyList::iterator Find(const std::string& web_session_id); |
| 57 | 59 |
| 58 // Deletes the entry pointed to by |position|. | 60 // Deletes the entry pointed to by |position|. |
| 59 void Erase(KeyList::iterator position); | 61 void Erase(KeyList::iterator position); |
| 60 | 62 |
| 61 KeyList key_list_; | 63 KeyList key_list_; |
| 62 | 64 |
| 63 DISALLOW_COPY_AND_ASSIGN(SessionIdDecryptionKeyMap); | 65 DISALLOW_COPY_AND_ASSIGN(SessionIdDecryptionKeyMap); |
| 64 }; | 66 }; |
| 65 | 67 |
| 66 void AesDecryptor::SessionIdDecryptionKeyMap::Insert( | 68 void AesDecryptor::SessionIdDecryptionKeyMap::Insert( |
| 67 uint32 session_id, | 69 const std::string& web_session_id, |
| 68 scoped_ptr<DecryptionKey> decryption_key) { | 70 scoped_ptr<DecryptionKey> decryption_key) { |
| 69 KeyList::iterator it = Find(session_id); | 71 KeyList::iterator it = Find(web_session_id); |
| 70 if (it != key_list_.end()) | 72 if (it != key_list_.end()) |
| 71 Erase(it); | 73 Erase(it); |
| 72 DecryptionKey* raw_ptr = decryption_key.release(); | 74 DecryptionKey* raw_ptr = decryption_key.release(); |
| 73 key_list_.push_front(std::make_pair(session_id, raw_ptr)); | 75 key_list_.push_front(std::make_pair(web_session_id, raw_ptr)); |
| 74 } | 76 } |
| 75 | 77 |
| 76 void AesDecryptor::SessionIdDecryptionKeyMap::Erase(const uint32 session_id) { | 78 void AesDecryptor::SessionIdDecryptionKeyMap::Erase( |
| 77 KeyList::iterator it = Find(session_id); | 79 const std::string& web_session_id) { |
| 80 KeyList::iterator it = Find(web_session_id); | |
| 78 if (it == key_list_.end()) | 81 if (it == key_list_.end()) |
| 79 return; | 82 return; |
| 80 Erase(it); | 83 Erase(it); |
| 81 } | 84 } |
| 82 | 85 |
| 83 AesDecryptor::SessionIdDecryptionKeyMap::KeyList::iterator | 86 AesDecryptor::SessionIdDecryptionKeyMap::KeyList::iterator |
| 84 AesDecryptor::SessionIdDecryptionKeyMap::Find(const uint32 session_id) { | 87 AesDecryptor::SessionIdDecryptionKeyMap::Find( |
| 88 const std::string& web_session_id) { | |
| 85 for (KeyList::iterator it = key_list_.begin(); it != key_list_.end(); ++it) { | 89 for (KeyList::iterator it = key_list_.begin(); it != key_list_.end(); ++it) { |
| 86 if (it->first == session_id) | 90 if (it->first == web_session_id) |
| 87 return it; | 91 return it; |
| 88 } | 92 } |
| 89 return key_list_.end(); | 93 return key_list_.end(); |
| 90 } | 94 } |
| 91 | 95 |
| 92 void AesDecryptor::SessionIdDecryptionKeyMap::Erase( | 96 void AesDecryptor::SessionIdDecryptionKeyMap::Erase( |
| 93 KeyList::iterator position) { | 97 KeyList::iterator position) { |
| 94 DCHECK(position->second); | 98 DCHECK(position->second); |
| 95 delete position->second; | 99 delete position->second; |
| 96 key_list_.erase(position); | 100 key_list_.erase(position); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 DCHECK_EQ(decrypted_text.size(), encrypted_text.size()); | 212 DCHECK_EQ(decrypted_text.size(), encrypted_text.size()); |
| 209 | 213 |
| 210 scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( | 214 scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( |
| 211 reinterpret_cast<const uint8*>(sample), sample_size); | 215 reinterpret_cast<const uint8*>(sample), sample_size); |
| 212 CopySubsamples(subsamples, kDstContainsClearBytes, | 216 CopySubsamples(subsamples, kDstContainsClearBytes, |
| 213 reinterpret_cast<const uint8*>(decrypted_text.data()), | 217 reinterpret_cast<const uint8*>(decrypted_text.data()), |
| 214 output->writable_data()); | 218 output->writable_data()); |
| 215 return output; | 219 return output; |
| 216 } | 220 } |
| 217 | 221 |
| 218 AesDecryptor::AesDecryptor(const SessionCreatedCB& session_created_cb, | 222 AesDecryptor::AesDecryptor(const SessionMessageCB& session_message_cb) |
| 219 const SessionMessageCB& session_message_cb, | 223 : session_message_cb_(session_message_cb) { |
| 220 const SessionReadyCB& session_ready_cb, | 224 DCHECK(!session_message_cb_.is_null()); |
| 221 const SessionClosedCB& session_closed_cb, | 225 } |
| 222 const SessionErrorCB& session_error_cb) | |
| 223 : session_created_cb_(session_created_cb), | |
| 224 session_message_cb_(session_message_cb), | |
| 225 session_ready_cb_(session_ready_cb), | |
| 226 session_closed_cb_(session_closed_cb), | |
| 227 session_error_cb_(session_error_cb) {} | |
| 228 | 226 |
| 229 AesDecryptor::~AesDecryptor() { | 227 AesDecryptor::~AesDecryptor() { |
| 230 key_map_.clear(); | 228 key_map_.clear(); |
| 231 } | 229 } |
| 232 | 230 |
| 233 bool AesDecryptor::CreateSession(uint32 session_id, | 231 void AesDecryptor::CreateSession(const std::string& init_data_type, |
| 234 const std::string& content_type, | |
| 235 const uint8* init_data, | 232 const uint8* init_data, |
| 236 int init_data_length) { | 233 int init_data_length, |
| 237 // Validate that this is a new session. | 234 SessionType session_type, |
| 238 DCHECK(valid_sessions_.find(session_id) == valid_sessions_.end()); | 235 scoped_ptr<MediaKeysSessionPromise> promise) { |
| 239 valid_sessions_.insert(session_id); | 236 std::string web_session_id(base::UintToString(next_web_session_id_++)); |
| 237 valid_sessions_.insert(web_session_id); | |
| 240 | 238 |
| 241 std::string web_session_id_string(base::UintToString(next_web_session_id_++)); | 239 // For now, the AesDecryptor does not care about |init_data_type| or |
| 242 | 240 // |session_type|; just resolve the promise and then fire a message event |
| 243 // For now, the AesDecryptor does not care about |content_type|; | 241 // with the |init_data| as the request. |
| 244 // just fire the event with the |init_data| as the request. | |
| 245 std::vector<uint8> message; | 242 std::vector<uint8> message; |
| 246 if (init_data && init_data_length) | 243 if (init_data && init_data_length) |
| 247 message.assign(init_data, init_data + init_data_length); | 244 message.assign(init_data, init_data + init_data_length); |
| 248 | 245 |
| 249 session_created_cb_.Run(session_id, web_session_id_string); | 246 promise->resolve(web_session_id); |
| 250 session_message_cb_.Run(session_id, message, std::string()); | 247 promise.reset(); |
| 251 return true; | 248 |
| 249 session_message_cb_.Run(web_session_id, message, std::string()); | |
| 252 } | 250 } |
| 253 | 251 |
| 254 void AesDecryptor::LoadSession(uint32 session_id, | 252 void AesDecryptor::LoadSession(const std::string& web_session_id, |
| 255 const std::string& web_session_id) { | 253 scoped_ptr<MediaKeysSessionPromise> promise) { |
| 256 // TODO(xhwang): Change this to NOTREACHED() when blink checks for key systems | 254 // TODO(xhwang): Change this to NOTREACHED() when blink checks for key systems |
| 257 // that do not support loadSession. See http://crbug.com/342481 | 255 // that do not support loadSession. See http://crbug.com/342481 |
| 258 session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); | 256 promise->reject("NotSupportedError", 0, "LoadSession() is not implemented."); |
| 257 promise.reset(); | |
| 259 } | 258 } |
| 260 | 259 |
| 261 void AesDecryptor::UpdateSession(uint32 session_id, | 260 void AesDecryptor::UpdateSession(const std::string& web_session_id, |
| 262 const uint8* response, | 261 const uint8* response, |
| 263 int response_length) { | 262 int response_length, |
| 263 scoped_ptr<MediaKeysSessionPromise> promise) { | |
| 264 CHECK(response); | 264 CHECK(response); |
| 265 CHECK_GT(response_length, 0); | 265 CHECK_GT(response_length, 0); |
| 266 DCHECK(valid_sessions_.find(session_id) != valid_sessions_.end()); | 266 |
| 267 if (valid_sessions_.find(web_session_id) == valid_sessions_.end()) { | |
| 268 promise->reject("InvalidStateError", 0, "Session does not exist."); | |
| 269 promise.reset(); | |
|
xhwang
2014/05/05 20:46:42
The |promise| will go out of scope automatically,
jrummell
2014/05/08 23:37:45
Done.
| |
| 270 return; | |
| 271 } | |
| 267 | 272 |
| 268 std::string key_string(reinterpret_cast<const char*>(response), | 273 std::string key_string(reinterpret_cast<const char*>(response), |
| 269 response_length); | 274 response_length); |
| 275 | |
| 270 KeyIdAndKeyPairs keys; | 276 KeyIdAndKeyPairs keys; |
| 271 if (!ExtractKeysFromJWKSet(key_string, &keys)) { | 277 if (!ExtractKeysFromJWKSet(key_string, &keys)) { |
| 272 session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); | 278 promise->reject( |
| 279 "EncodingError", 0, "response is not a valid JSON Web Key Set."); | |
| 280 promise.reset(); | |
| 273 return; | 281 return; |
| 274 } | 282 } |
| 275 | 283 |
| 276 // Make sure that at least one key was extracted. | 284 // Make sure that at least one key was extracted. |
| 277 if (keys.empty()) { | 285 if (keys.empty()) { |
| 278 session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); | 286 promise->reject("SyntaxError", 0, "response does not contain any keys."); |
| 287 promise.reset(); | |
| 279 return; | 288 return; |
| 280 } | 289 } |
| 281 | 290 |
| 282 for (KeyIdAndKeyPairs::iterator it = keys.begin(); it != keys.end(); ++it) { | 291 for (KeyIdAndKeyPairs::iterator it = keys.begin(); it != keys.end(); ++it) { |
| 283 if (it->second.length() != | 292 if (it->second.length() != |
| 284 static_cast<size_t>(DecryptConfig::kDecryptionKeySize)) { | 293 static_cast<size_t>(DecryptConfig::kDecryptionKeySize)) { |
| 285 DVLOG(1) << "Invalid key length: " << key_string.length(); | 294 DVLOG(1) << "Invalid key length: " << key_string.length(); |
| 286 session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); | 295 promise->reject("SyntaxError", 0, "Invalid key length."); |
| 296 promise.reset(); | |
| 287 return; | 297 return; |
| 288 } | 298 } |
| 289 if (!AddDecryptionKey(session_id, it->first, it->second)) { | 299 if (!AddDecryptionKey(web_session_id, it->first, it->second)) { |
| 290 session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); | 300 promise->reject("InvalidModificationError", 0, "Unable to add key."); |
| 301 promise.reset(); | |
| 291 return; | 302 return; |
| 292 } | 303 } |
| 293 } | 304 } |
| 294 | 305 |
| 295 { | 306 { |
| 296 base::AutoLock auto_lock(new_key_cb_lock_); | 307 base::AutoLock auto_lock(new_key_cb_lock_); |
| 297 | 308 |
| 298 if (!new_audio_key_cb_.is_null()) | 309 if (!new_audio_key_cb_.is_null()) |
| 299 new_audio_key_cb_.Run(); | 310 new_audio_key_cb_.Run(); |
| 300 | 311 |
| 301 if (!new_video_key_cb_.is_null()) | 312 if (!new_video_key_cb_.is_null()) |
| 302 new_video_key_cb_.Run(); | 313 new_video_key_cb_.Run(); |
| 303 } | 314 } |
| 304 | 315 |
| 305 session_ready_cb_.Run(session_id); | 316 promise->resolve(); |
| 317 promise.reset(); | |
| 306 } | 318 } |
| 307 | 319 |
| 308 void AesDecryptor::ReleaseSession(uint32 session_id) { | 320 void AesDecryptor::ReleaseSession(const std::string& web_session_id, |
| 321 scoped_ptr<MediaKeysSessionPromise> promise) { | |
| 309 // Validate that this is a reference to an active session and then forget it. | 322 // Validate that this is a reference to an active session and then forget it. |
| 310 std::set<uint32>::iterator it = valid_sessions_.find(session_id); | 323 std::set<std::string>::iterator it = valid_sessions_.find(web_session_id); |
| 311 DCHECK(it != valid_sessions_.end()); | 324 if (it == valid_sessions_.end()) { |
| 325 promise->reject("InvalidStateError", 0, "Session does not exist."); | |
| 326 promise.reset(); | |
| 327 return; | |
| 328 } | |
| 329 | |
| 312 valid_sessions_.erase(it); | 330 valid_sessions_.erase(it); |
| 313 | 331 |
| 314 DeleteKeysForSession(session_id); | 332 DeleteKeysForSession(web_session_id); |
| 315 session_closed_cb_.Run(session_id); | 333 promise->resolve(); |
| 334 promise.reset(); | |
| 316 } | 335 } |
| 317 | 336 |
| 318 Decryptor* AesDecryptor::GetDecryptor() { | 337 Decryptor* AesDecryptor::GetDecryptor() { |
| 319 return this; | 338 return this; |
| 320 } | 339 } |
| 321 | 340 |
| 322 void AesDecryptor::RegisterNewKeyCB(StreamType stream_type, | 341 void AesDecryptor::RegisterNewKeyCB(StreamType stream_type, |
| 323 const NewKeyCB& new_key_cb) { | 342 const NewKeyCB& new_key_cb) { |
| 324 base::AutoLock auto_lock(new_key_cb_lock_); | 343 base::AutoLock auto_lock(new_key_cb_lock_); |
| 325 | 344 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 397 } | 416 } |
| 398 | 417 |
| 399 void AesDecryptor::ResetDecoder(StreamType stream_type) { | 418 void AesDecryptor::ResetDecoder(StreamType stream_type) { |
| 400 NOTREACHED() << "AesDecryptor does not support audio/video decoding"; | 419 NOTREACHED() << "AesDecryptor does not support audio/video decoding"; |
| 401 } | 420 } |
| 402 | 421 |
| 403 void AesDecryptor::DeinitializeDecoder(StreamType stream_type) { | 422 void AesDecryptor::DeinitializeDecoder(StreamType stream_type) { |
| 404 NOTREACHED() << "AesDecryptor does not support audio/video decoding"; | 423 NOTREACHED() << "AesDecryptor does not support audio/video decoding"; |
| 405 } | 424 } |
| 406 | 425 |
| 407 bool AesDecryptor::AddDecryptionKey(const uint32 session_id, | 426 bool AesDecryptor::AddDecryptionKey(const std::string& web_session_id, |
| 408 const std::string& key_id, | 427 const std::string& key_id, |
| 409 const std::string& key_string) { | 428 const std::string& key_string) { |
| 410 scoped_ptr<DecryptionKey> decryption_key(new DecryptionKey(key_string)); | 429 scoped_ptr<DecryptionKey> decryption_key(new DecryptionKey(key_string)); |
| 411 if (!decryption_key) { | 430 if (!decryption_key) { |
| 412 DVLOG(1) << "Could not create key."; | 431 DVLOG(1) << "Could not create key."; |
| 413 return false; | 432 return false; |
| 414 } | 433 } |
| 415 | 434 |
| 416 if (!decryption_key->Init()) { | 435 if (!decryption_key->Init()) { |
| 417 DVLOG(1) << "Could not initialize decryption key."; | 436 DVLOG(1) << "Could not initialize decryption key."; |
| 418 return false; | 437 return false; |
| 419 } | 438 } |
| 420 | 439 |
| 421 base::AutoLock auto_lock(key_map_lock_); | 440 base::AutoLock auto_lock(key_map_lock_); |
| 422 KeyIdToSessionKeysMap::iterator key_id_entry = key_map_.find(key_id); | 441 KeyIdToSessionKeysMap::iterator key_id_entry = key_map_.find(key_id); |
| 423 if (key_id_entry != key_map_.end()) { | 442 if (key_id_entry != key_map_.end()) { |
| 424 key_id_entry->second->Insert(session_id, decryption_key.Pass()); | 443 key_id_entry->second->Insert(web_session_id, decryption_key.Pass()); |
| 425 return true; | 444 return true; |
| 426 } | 445 } |
| 427 | 446 |
| 428 // |key_id| not found, so need to create new entry. | 447 // |key_id| not found, so need to create new entry. |
| 429 scoped_ptr<SessionIdDecryptionKeyMap> inner_map( | 448 scoped_ptr<SessionIdDecryptionKeyMap> inner_map( |
| 430 new SessionIdDecryptionKeyMap()); | 449 new SessionIdDecryptionKeyMap()); |
| 431 inner_map->Insert(session_id, decryption_key.Pass()); | 450 inner_map->Insert(web_session_id, decryption_key.Pass()); |
| 432 key_map_.add(key_id, inner_map.Pass()); | 451 key_map_.add(key_id, inner_map.Pass()); |
| 433 return true; | 452 return true; |
| 434 } | 453 } |
| 435 | 454 |
| 436 AesDecryptor::DecryptionKey* AesDecryptor::GetKey( | 455 AesDecryptor::DecryptionKey* AesDecryptor::GetKey( |
| 437 const std::string& key_id) const { | 456 const std::string& key_id) const { |
| 438 base::AutoLock auto_lock(key_map_lock_); | 457 base::AutoLock auto_lock(key_map_lock_); |
| 439 KeyIdToSessionKeysMap::const_iterator key_id_found = key_map_.find(key_id); | 458 KeyIdToSessionKeysMap::const_iterator key_id_found = key_map_.find(key_id); |
| 440 if (key_id_found == key_map_.end()) | 459 if (key_id_found == key_map_.end()) |
| 441 return NULL; | 460 return NULL; |
| 442 | 461 |
| 443 // Return the key from the "latest" session_id entry. | 462 // Return the key from the "latest" session_id entry. |
| 444 return key_id_found->second->LatestDecryptionKey(); | 463 return key_id_found->second->LatestDecryptionKey(); |
| 445 } | 464 } |
| 446 | 465 |
| 447 void AesDecryptor::DeleteKeysForSession(const uint32 session_id) { | 466 void AesDecryptor::DeleteKeysForSession(const std::string& web_session_id) { |
| 448 base::AutoLock auto_lock(key_map_lock_); | 467 base::AutoLock auto_lock(key_map_lock_); |
| 449 | 468 |
| 450 // Remove all keys associated with |session_id|. Since the data is optimized | 469 // Remove all keys associated with |web_session_id|. Since the data is |
| 451 // for access in GetKey(), we need to look at each entry in |key_map_|. | 470 // optimized for access in GetKey(), we need to look at each entry in |
| 471 // |key_map_|. | |
| 452 KeyIdToSessionKeysMap::iterator it = key_map_.begin(); | 472 KeyIdToSessionKeysMap::iterator it = key_map_.begin(); |
| 453 while (it != key_map_.end()) { | 473 while (it != key_map_.end()) { |
| 454 it->second->Erase(session_id); | 474 it->second->Erase(web_session_id); |
| 455 if (it->second->Empty()) { | 475 if (it->second->Empty()) { |
| 456 // Need to get rid of the entry for this key_id. This will mess up the | 476 // Need to get rid of the entry for this key_id. This will mess up the |
| 457 // iterator, so we need to increment it first. | 477 // iterator, so we need to increment it first. |
| 458 KeyIdToSessionKeysMap::iterator current = it; | 478 KeyIdToSessionKeysMap::iterator current = it; |
| 459 ++it; | 479 ++it; |
| 460 key_map_.erase(current); | 480 key_map_.erase(current); |
| 461 } else { | 481 } else { |
| 462 ++it; | 482 ++it; |
| 463 } | 483 } |
| 464 } | 484 } |
| 465 } | 485 } |
| 466 | 486 |
| 467 AesDecryptor::DecryptionKey::DecryptionKey(const std::string& secret) | 487 AesDecryptor::DecryptionKey::DecryptionKey(const std::string& secret) |
| 468 : secret_(secret) { | 488 : secret_(secret) { |
| 469 } | 489 } |
| 470 | 490 |
| 471 AesDecryptor::DecryptionKey::~DecryptionKey() {} | 491 AesDecryptor::DecryptionKey::~DecryptionKey() {} |
| 472 | 492 |
| 473 bool AesDecryptor::DecryptionKey::Init() { | 493 bool AesDecryptor::DecryptionKey::Init() { |
| 474 CHECK(!secret_.empty()); | 494 CHECK(!secret_.empty()); |
| 475 decryption_key_.reset(crypto::SymmetricKey::Import( | 495 decryption_key_.reset(crypto::SymmetricKey::Import( |
| 476 crypto::SymmetricKey::AES, secret_)); | 496 crypto::SymmetricKey::AES, secret_)); |
| 477 if (!decryption_key_) | 497 if (!decryption_key_) |
| 478 return false; | 498 return false; |
| 479 return true; | 499 return true; |
| 480 } | 500 } |
| 481 | 501 |
| 482 } // namespace media | 502 } // namespace media |
| OLD | NEW |