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/cdm_promise.h" | |
16 #include "media/base/decoder_buffer.h" | 17 #include "media/base/decoder_buffer.h" |
17 #include "media/base/decrypt_config.h" | 18 #include "media/base/decrypt_config.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<CdmNewSessionPromise> 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 |
ddorwin
2014/05/13 22:44:02
TODO: Fix this.
jrummell
2014/05/15 22:38:09
Done.
| |
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 |
251 return true; | 248 session_message_cb_.Run(web_session_id, message, std::string()); |
252 } | 249 } |
253 | 250 |
254 void AesDecryptor::LoadSession(uint32 session_id, | 251 void AesDecryptor::LoadSession(const std::string& web_session_id, |
255 const std::string& web_session_id) { | 252 scoped_ptr<CdmNewSessionPromise> promise) { |
256 // TODO(xhwang): Change this to NOTREACHED() when blink checks for key systems | 253 // TODO(xhwang): Change this to NOTREACHED() when blink checks for key systems |
257 // that do not support loadSession. See http://crbug.com/342481 | 254 // that do not support loadSession. See http://crbug.com/342481 |
258 session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); | 255 promise->reject(MEDIA_KEYS_EXCEPTION_NOT_SUPPORTED_ERROR, |
256 0, | |
257 "LoadSession() is not implemented."); | |
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<CdmChangeSessionPromise> 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()) { | |
ddorwin
2014/05/13 22:44:02
Why is this no longer a DCHECK? Can't happen in WD
jrummell
2014/05/15 22:38:09
Prefixed was handling it prior to this when conver
| |
268 promise->reject( | |
269 MEDIA_KEYS_EXCEPTION_INVALID_STATE_ERROR, 0, "Session does not exist."); | |
ddorwin
2014/05/13 22:44:02
This is really InvalidAccessError - invalid parame
jrummell
2014/05/15 22:38:09
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(MEDIA_KEYS_EXCEPTION_SYNTAX_ERROR, |
ddorwin
2014/05/13 22:44:02
Probably InvalidAccessError. Maybe DataError, but
jrummell
2014/05/15 22:38:09
Done.
| |
279 0, | |
280 "response is not a valid JSON Web Key Set."); | |
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(MEDIA_KEYS_EXCEPTION_SYNTAX_ERROR, |
ddorwin
2014/05/13 22:44:02
InvalidAccessError
jrummell
2014/05/15 22:38:09
Done.
| |
287 0, | |
288 "response does not contain any keys."); | |
279 return; | 289 return; |
280 } | 290 } |
281 | 291 |
282 for (KeyIdAndKeyPairs::iterator it = keys.begin(); it != keys.end(); ++it) { | 292 for (KeyIdAndKeyPairs::iterator it = keys.begin(); it != keys.end(); ++it) { |
283 if (it->second.length() != | 293 if (it->second.length() != |
284 static_cast<size_t>(DecryptConfig::kDecryptionKeySize)) { | 294 static_cast<size_t>(DecryptConfig::kDecryptionKeySize)) { |
285 DVLOG(1) << "Invalid key length: " << key_string.length(); | 295 DVLOG(1) << "Invalid key length: " << key_string.length(); |
286 session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); | 296 promise->reject( |
297 MEDIA_KEYS_EXCEPTION_SYNTAX_ERROR, 0, "Invalid key length."); | |
ddorwin
2014/05/13 22:44:02
InvalidAccessError
jrummell
2014/05/15 22:38:09
Done.
| |
287 return; | 298 return; |
288 } | 299 } |
289 if (!AddDecryptionKey(session_id, it->first, it->second)) { | 300 if (!AddDecryptionKey(web_session_id, it->first, it->second)) { |
290 session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); | 301 promise->reject(MEDIA_KEYS_EXCEPTION_INVALID_MODIFICATION_ERROR, |
ddorwin
2014/05/13 22:44:02
I think this is also InvalidAccessError, since it
jrummell
2014/05/15 22:38:09
Done.
| |
302 0, | |
303 "Unable to add key."); | |
291 return; | 304 return; |
292 } | 305 } |
293 } | 306 } |
294 | 307 |
295 { | 308 { |
296 base::AutoLock auto_lock(new_key_cb_lock_); | 309 base::AutoLock auto_lock(new_key_cb_lock_); |
297 | 310 |
298 if (!new_audio_key_cb_.is_null()) | 311 if (!new_audio_key_cb_.is_null()) |
299 new_audio_key_cb_.Run(); | 312 new_audio_key_cb_.Run(); |
300 | 313 |
301 if (!new_video_key_cb_.is_null()) | 314 if (!new_video_key_cb_.is_null()) |
302 new_video_key_cb_.Run(); | 315 new_video_key_cb_.Run(); |
303 } | 316 } |
304 | 317 |
305 session_ready_cb_.Run(session_id); | 318 promise->resolve(); |
306 } | 319 } |
307 | 320 |
308 void AesDecryptor::ReleaseSession(uint32 session_id) { | 321 void AesDecryptor::ReleaseSession(const std::string& web_session_id, |
322 scoped_ptr<CdmChangeSessionPromise> promise) { | |
309 // Validate that this is a reference to an active session and then forget it. | 323 // 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); | 324 std::set<std::string>::iterator it = valid_sessions_.find(web_session_id); |
311 DCHECK(it != valid_sessions_.end()); | 325 if (it == valid_sessions_.end()) { |
ddorwin
2014/05/13 22:44:02
ditto on DCHECK and exception.
jrummell
2014/05/15 22:38:09
Done.
| |
326 promise->reject( | |
327 MEDIA_KEYS_EXCEPTION_INVALID_STATE_ERROR, 0, "Session does not exist."); | |
328 return; | |
329 } | |
330 | |
312 valid_sessions_.erase(it); | 331 valid_sessions_.erase(it); |
313 | 332 |
314 DeleteKeysForSession(session_id); | 333 DeleteKeysForSession(web_session_id); |
315 session_closed_cb_.Run(session_id); | 334 promise->resolve(); |
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) { |
ddorwin
2014/05/13 22:44:02
This can't happen. We should remove it.
jrummell
2014/05/15 22:38:09
Done.
| |
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()) { |
ddorwin
2014/05/13 22:44:02
That leaves this.
| |
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 |