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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 | 217 |
218 scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( | 218 scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( |
219 reinterpret_cast<const uint8*>(sample), sample_size); | 219 reinterpret_cast<const uint8*>(sample), sample_size); |
220 CopySubsamples(subsamples, kDstContainsClearBytes, | 220 CopySubsamples(subsamples, kDstContainsClearBytes, |
221 reinterpret_cast<const uint8*>(decrypted_text.data()), | 221 reinterpret_cast<const uint8*>(decrypted_text.data()), |
222 output->writable_data()); | 222 output->writable_data()); |
223 return output; | 223 return output; |
224 } | 224 } |
225 | 225 |
226 AesDecryptor::AesDecryptor(const SessionMessageCB& session_message_cb, | 226 AesDecryptor::AesDecryptor(const SessionMessageCB& session_message_cb, |
227 const SessionClosedCB& session_closed_cb) | 227 const SessionClosedCB& session_closed_cb, |
| 228 const SessionKeysChangeCB& session_keys_change_cb) |
228 : session_message_cb_(session_message_cb), | 229 : session_message_cb_(session_message_cb), |
229 session_closed_cb_(session_closed_cb) { | 230 session_closed_cb_(session_closed_cb), |
| 231 session_keys_change_cb_(session_keys_change_cb) { |
230 DCHECK(!session_message_cb_.is_null()); | 232 DCHECK(!session_message_cb_.is_null()); |
231 DCHECK(!session_closed_cb_.is_null()); | 233 DCHECK(!session_closed_cb_.is_null()); |
| 234 DCHECK(!session_keys_change_cb_.is_null()); |
232 } | 235 } |
233 | 236 |
234 AesDecryptor::~AesDecryptor() { | 237 AesDecryptor::~AesDecryptor() { |
235 key_map_.clear(); | 238 key_map_.clear(); |
236 } | 239 } |
237 | 240 |
| 241 void AesDecryptor::SetServerCertificate(const uint8* certificate_data, |
| 242 int certificate_data_length, |
| 243 scoped_ptr<SimpleCdmPromise> promise) { |
| 244 promise->reject( |
| 245 NOT_SUPPORTED_ERROR, 0, "SetServerCertificate() is not supported."); |
| 246 } |
| 247 |
238 void AesDecryptor::CreateSession(const std::string& init_data_type, | 248 void AesDecryptor::CreateSession(const std::string& init_data_type, |
239 const uint8* init_data, | 249 const uint8* init_data, |
240 int init_data_length, | 250 int init_data_length, |
241 SessionType session_type, | 251 SessionType session_type, |
242 scoped_ptr<NewSessionCdmPromise> promise) { | 252 scoped_ptr<NewSessionCdmPromise> promise) { |
243 std::string web_session_id(base::UintToString(next_web_session_id_++)); | 253 std::string web_session_id(base::UintToString(next_web_session_id_++)); |
244 valid_sessions_.insert(web_session_id); | 254 valid_sessions_.insert(web_session_id); |
245 | 255 |
246 // For now, the AesDecryptor does not care about |init_data_type| or | 256 // For now, the AesDecryptor does not care about |init_data_type| or |
247 // |session_type|; just resolve the promise and then fire a message event | 257 // |session_type|; just resolve the promise and then fire a message event |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 base::AutoLock auto_lock(new_key_cb_lock_); | 321 base::AutoLock auto_lock(new_key_cb_lock_); |
312 | 322 |
313 if (!new_audio_key_cb_.is_null()) | 323 if (!new_audio_key_cb_.is_null()) |
314 new_audio_key_cb_.Run(); | 324 new_audio_key_cb_.Run(); |
315 | 325 |
316 if (!new_video_key_cb_.is_null()) | 326 if (!new_video_key_cb_.is_null()) |
317 new_video_key_cb_.Run(); | 327 new_video_key_cb_.Run(); |
318 } | 328 } |
319 | 329 |
320 promise->resolve(); | 330 promise->resolve(); |
| 331 |
| 332 // Assume that at least 1 new key has been successfully added and thus |
| 333 // sending true. |
| 334 session_keys_change_cb_.Run(web_session_id, true); |
| 335 } |
| 336 |
| 337 void AesDecryptor::CloseSession(const std::string& web_session_id, |
| 338 scoped_ptr<SimpleCdmPromise> promise) { |
| 339 // Validate that this is a reference to an active session and then forget it. |
| 340 std::set<std::string>::iterator it = valid_sessions_.find(web_session_id); |
| 341 DCHECK(it != valid_sessions_.end()); |
| 342 |
| 343 valid_sessions_.erase(it); |
| 344 |
| 345 // Close the session. |
| 346 DeleteKeysForSession(web_session_id); |
| 347 promise->resolve(); |
| 348 session_closed_cb_.Run(web_session_id); |
| 349 } |
| 350 |
| 351 void AesDecryptor::RemoveSession(const std::string& web_session_id, |
| 352 scoped_ptr<SimpleCdmPromise> promise) { |
| 353 // AesDecryptor doesn't keep any persistent data, so this should be |
| 354 // NOT_REACHED(). |
| 355 // TODO(jrummell): Make sure persistent session types are rejected. |
| 356 // http://crbug.com/384152. |
| 357 // |
| 358 // However, v0.1b calls to CancelKeyRequest() will call this, so close the |
| 359 // session, if it exists. |
| 360 // TODO(jrummell): Remove the close() call when prefixed EME is removed. |
| 361 // http://crbug.com/249976. |
| 362 if (valid_sessions_.find(web_session_id) != valid_sessions_.end()) { |
| 363 CloseSession(web_session_id, promise.Pass()); |
| 364 return; |
| 365 } |
| 366 |
| 367 promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist."); |
321 } | 368 } |
322 | 369 |
323 void AesDecryptor::GetUsableKeyIds(const std::string& web_session_id, | 370 void AesDecryptor::GetUsableKeyIds(const std::string& web_session_id, |
324 scoped_ptr<KeyIdsPromise> promise) { | 371 scoped_ptr<KeyIdsPromise> promise) { |
325 // Since |web_session_id| is not provided by the user, this should never | 372 // Since |web_session_id| is not provided by the user, this should never |
326 // happen. | 373 // happen. |
327 DCHECK(valid_sessions_.find(web_session_id) != valid_sessions_.end()); | 374 DCHECK(valid_sessions_.find(web_session_id) != valid_sessions_.end()); |
328 | 375 |
329 KeyIdsVector keyids; | 376 KeyIdsVector keyids; |
330 base::AutoLock auto_lock(key_map_lock_); | 377 base::AutoLock auto_lock(key_map_lock_); |
331 for (KeyIdToSessionKeysMap::iterator it = key_map_.begin(); | 378 for (KeyIdToSessionKeysMap::iterator it = key_map_.begin(); |
332 it != key_map_.end(); | 379 it != key_map_.end(); |
333 ++it) { | 380 ++it) { |
334 if (it->second->Contains(web_session_id)) | 381 if (it->second->Contains(web_session_id)) |
335 keyids.push_back(std::vector<uint8>(it->first.begin(), it->first.end())); | 382 keyids.push_back(std::vector<uint8>(it->first.begin(), it->first.end())); |
336 } | 383 } |
337 promise->resolve(keyids); | 384 promise->resolve(keyids); |
338 } | 385 } |
339 | 386 |
340 void AesDecryptor::ReleaseSession(const std::string& web_session_id, | |
341 scoped_ptr<SimpleCdmPromise> promise) { | |
342 // Validate that this is a reference to an active session and then forget it. | |
343 std::set<std::string>::iterator it = valid_sessions_.find(web_session_id); | |
344 // TODO(jrummell): Convert back to a DCHECK once prefixed EME is removed. | |
345 if (it == valid_sessions_.end()) { | |
346 promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist."); | |
347 return; | |
348 } | |
349 | |
350 valid_sessions_.erase(it); | |
351 | |
352 // Close the session. | |
353 DeleteKeysForSession(web_session_id); | |
354 promise->resolve(); | |
355 session_closed_cb_.Run(web_session_id); | |
356 } | |
357 | |
358 Decryptor* AesDecryptor::GetDecryptor() { | 387 Decryptor* AesDecryptor::GetDecryptor() { |
359 return this; | 388 return this; |
360 } | 389 } |
361 | 390 |
362 void AesDecryptor::RegisterNewKeyCB(StreamType stream_type, | 391 void AesDecryptor::RegisterNewKeyCB(StreamType stream_type, |
363 const NewKeyCB& new_key_cb) { | 392 const NewKeyCB& new_key_cb) { |
364 base::AutoLock auto_lock(new_key_cb_lock_); | 393 base::AutoLock auto_lock(new_key_cb_lock_); |
365 | 394 |
366 switch (stream_type) { | 395 switch (stream_type) { |
367 case kAudio: | 396 case kAudio: |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 bool AesDecryptor::DecryptionKey::Init() { | 538 bool AesDecryptor::DecryptionKey::Init() { |
510 CHECK(!secret_.empty()); | 539 CHECK(!secret_.empty()); |
511 decryption_key_.reset(crypto::SymmetricKey::Import( | 540 decryption_key_.reset(crypto::SymmetricKey::Import( |
512 crypto::SymmetricKey::AES, secret_)); | 541 crypto::SymmetricKey::AES, secret_)); |
513 if (!decryption_key_) | 542 if (!decryption_key_) |
514 return false; | 543 return false; |
515 return true; | 544 return true; |
516 } | 545 } |
517 | 546 |
518 } // namespace media | 547 } // namespace media |
OLD | NEW |